#include "Test_png.h"
#include "png.h"
#include "zlib.h"
#include "sys_lcd_gui_argb32.h"
#include "sys_timer.h"
#include "sys_uart.h"
#include "stdlib.h"
#include "sys_delay.h"
#include "test_image.h"

png_structp png_ptr;	// png解码结构体
png_infop info_ptr;		// png解码信息
png_infop end_info_ptr; // png解码结束信息

unsigned char *image_p;
unsigned char *image_s;
unsigned int len_p;
unsigned int len_s;

ImageSource imagesource; // 图片源
Image_inf image_inf;
/*****************************************************
** @函数名：PngReadCallback
** @描述  ：PNG读如数据回调函数
** @参数  ：png_ptr：
** @返回值：None
*****************************************************/
void PngReadCallback(png_structp png_ptr, png_byte *data, png_size_t length)
{
	ImageSource *isource = (ImageSource *)png_get_io_ptr(png_ptr);
	if ((isource->image_offset + length) <= isource->image_size)
	{
		memcpy(data, isource->image_data + isource->image_offset, length);
		isource->image_offset += length;
	}
}

/*****************************************************
** @函数名：Png_Decode
** @描述  ：PNG图片解码
** @参数  ：png_ptr：
** @返回值：None
*****************************************************/
uint32_t *Test;
int Png_Decode(unsigned char *image_data, unsigned int dataSize)
{
	int i, j, temp;
	int pos = 0;
	png_bytepp row_pointers; // 实际存储rgb数据的buf

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); // 初始化libpng，创建png读取的结构体
	if (png_ptr == NULL)
	{
		return 1;
	}
	info_ptr = png_create_info_struct(png_ptr); // 创建图片信息
	if (info_ptr == NULL)
	{
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return 2;
	}
	//	end_info_ptr = png_create_info_struct(png_ptr);
	//	if(end_info_ptr == NULL)
	//	{
	//		png_destroy_read_struct(&png_ptr, NULL, NULL);
	//		return 3;
	//	}
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, 0);
		return 4;
	}
	imagesource.image_data = image_data;
	imagesource.image_size = dataSize;
	imagesource.image_offset = 0;
	png_set_read_fn(png_ptr, &imagesource, PngReadCallback); // 设置图片读取回调函数，绑定数据数据函数
	png_set_sig_bytes(png_ptr, 0);
	// 读取文件信息，以及把数据转换为ARGB:8888格式,PNG_TRANSFORM_STRIP_ALPHA:从输入数据中删除亮度字节
	// png_read_png(png_ptr, info_ptr,PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_STRIP_ALPHA,0);  ]
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);
	image_inf.width = png_get_image_width(png_ptr, info_ptr);	  // 宽
	image_inf.height = png_get_image_height(png_ptr, info_ptr);	  // 高
	image_inf.channels = png_get_channels(png_ptr, info_ptr);	  // 通道数量
	image_inf.color_type = png_get_color_type(png_ptr, info_ptr); // 颜色类型
	image_inf.bit_depth = png_get_bit_depth(png_ptr, info_ptr);	  // 位深度

	row_pointers = png_get_rows(png_ptr, info_ptr);
	if ((image_inf.channels == 4) || (image_inf.color_type == PNG_COLOR_TYPE_RGB_ALPHA)) ////判断是24位还是32位
	{
		image_inf.alpha_flag = 1;								 // 记录是否有透明通道
		image_inf.size = image_inf.width * image_inf.height * 4; // 获得解码后的数据长度
		image_inf.ARGB = (png_bytep)malloc(image_inf.size);		 // 分配解码后存储数据的空间
		if (image_inf.ARGB == NULL)
		{
			png_read_end(png_ptr, info_ptr);
			png_destroy_read_struct(&png_ptr, &info_ptr, 0); // 释放资源
			return -1;
		}
		for (i = 0; i < image_inf.height; i++)
		{
			for (j = 0; j < image_inf.width * 4;)
			{
				image_inf.ARGB[pos++] = row_pointers[i][j + 2]; // R
				image_inf.ARGB[pos++] = row_pointers[i][j + 1]; // G
				image_inf.ARGB[pos++] = row_pointers[i][j + 0]; // B
				image_inf.ARGB[pos++] = row_pointers[i][j + 3]; // A：转换出来的数据是RGBA
				j = j + 4;
			}
		}
	}
	else if ((image_inf.channels == 3) || (image_inf.color_type == PNG_COLOR_TYPE_RGB)) // 24位颜色
	{
		image_inf.alpha_flag = 0;								 // 记录是否有透明通道
		image_inf.size = image_inf.width * image_inf.height * 4; // 获得解码后的数据长度
		image_inf.ARGB = (png_bytep)malloc(image_inf.size);		 // 分配解码后存储数据的空间
		if (image_inf.ARGB == NULL)
		{
			png_read_end(png_ptr, info_ptr);
			png_destroy_read_struct(&png_ptr, &info_ptr, 0); // 释放资源
			return -1;
		}
		temp = 3 * image_inf.width;
		for (i = 0; i < image_inf.height; i++)
		{
			for (j = 0; j < temp; j += 3)
			{
				image_inf.ARGB[pos++] = row_pointers[i][j + 2]; // R
				image_inf.ARGB[pos++] = row_pointers[i][j + 1]; // G
				image_inf.ARGB[pos++] = row_pointers[i][j + 0]; // B
				image_inf.ARGB[pos++] = 0xFF;
			}
		}
	}
	else
	{
		return -1;
	}
	Test = (uint32_t *)image_inf.ARGB;
	LCD_Draw_Picture32_ARGB32(140, 36, image_inf.width, image_inf.height, image_inf.ARGB); // 显示到LCD
	free(image_inf.ARGB);																   // 释放内存
	png_destroy_read_struct(&png_ptr, &info_ptr, 0);									   // 解码完成，释放资源
	return 0;
}

/*****************************************************
** @函数名：Test_png
** @描述  ：PNG图片解码测试
** @参数  ：
** @返回值：None
*****************************************************/
void Test_png(void)
{
	/*背景色*/
	LCD_Clear_ARGB32(0xFF0000FF);
	/*前景png图片*/
	int time = Read_time_ms();
	Png_Decode(_actest_image, sizeof(_actest_image));
	sysprintf("Time= %d ms\r\n", Read_time_ms() - time);
}
